// #pragma once
#ifndef THREAD_HPP
#define THREAD_HPP

#include <iostream>
#include <string>
#include <unistd.h>
#include <functional>
#include <pthread.h>
#include <vector>



//封装线程
namespace MyThread
{
    static int number = 1;
    using threadfunc_t = std::function<void*(void*)>;
    enum STATUS
    {
        NEW,
        RUNNING,
        STOP
    };

    std::string ToHex(pthread_t num)
    {
        char buffer[64];
        snprintf(buffer, sizeof(buffer), "0x%lx", num);
        return buffer;
    }

    class Thread
    {
    private:
        static void* run(void* args)
        {
            Thread* th = static_cast<Thread*>(args);
            pthread_setname_np(pthread_self(),th->_name.c_str());//设置线程名称
            
            th->_status = STATUS::RUNNING;
            if(!th->_join)
                th->EnableDecatch();
            th->_func_t(args);
            return nullptr;
        }

        void SetName()
        {
            _name = "Thread - " + std::to_string(number++);
        }

        // static void* Routine(void* args)
        // {
        //     while(true)
        //     {
        //         std::cout<<"I am a new pthread, my name is: "<<Name()
        //         <<", my id is: "<<ToHex(pthread_self())<<std::endl;
        //         sleep(1);
        //     }
        // }

        // static void* Routine(void* atgs)
        // {
        //     while(true)
        //     {
        //         std::cout<<"I am new pthread, id: "<<number-1<<std::endl;
        //         sleep(1);
        //     }
        // }
    public:
        Thread(threadfunc_t func_t) : _status(STATUS::NEW), _join(true), _func_t(func_t)
        {
            SetName();
        }

        bool Start() // 创建进程
        {
            if (_status == STATUS::RUNNING)
                return true;
            int n = ::pthread_create(&_id, nullptr, run, this);
            if (n != 0)
            {
                std::cerr << "pthread_create error" << std::endl;
                return false;
            }
            return true;
        }

        bool StopPthread() // 停止线程
        {
            if (_status == STATUS::RUNNING)
            {
                int n = ::pthread_cancel(_id);
                if (n != 0)
                {
                    std::cerr << "pthread_cancel error" << std::endl;
                    return false;
                }
                _status = STATUS::STOP;
                return true;
            }
            return false;
        }

        void EnableDecatch() // 启用分离
        {
            if (_status == STATUS::NEW)
                _join = false;
        }

        void EnableJoin() // 禁用分离:可以等待
        {
            if (_status == STATUS::NEW)
                _join = true;
        }

        bool Join() // 等待
        {
            if (_join)
            {
                int n = ::pthread_join(_id, nullptr);
                if (n != 0)
                {
                    std::cerr << "pthread_join error" << std::endl;
                    return false;
                }
                return true;
            }
            return false;
        }

        std::string GetName()
        {
            return _name;
        }

        ~Thread()
        {}

    private:
        std::string _name;
        bool _join;     // 是否分离
        pthread_t _id;  // 线程id
        STATUS _status; // 线程状态
        threadfunc_t _func_t;
    };

    // std::string Name()
    // {
    //     Thread th;
    //     return th.GetName();
    // }
};


#endif